//
//  MPMNetRequestModel.h
//  MiaoPai
//
//  Created by jiaxuzhou on 2017/5/24.
//  Copyright © 2017年 jiaxuzhou. All rights reserved.
//

#import "MPMNetRequestModel.h"

@interface MPMNetRequestModel ()

/// 请求方法
@property (nonatomic, assign) MPE_NetMethod enumNetMethod;

/// 是否显示无网络提示
@property (nonatomic, assign) BOOL isShowNoNetAlert;

/// 请求地址
@property (nonatomic, copy) NSString *strUrl;

/// 网络超时时间
@property (nonatomic, assign) CGFloat timeoutInterval;

/// 优先级
@property (nonatomic, assign) MPE_NetWorkPriority priorityTask;

/// 发送请求的类
@property (nonatomic, strong) Class classReq;

/// 请求参数
@property (nonatomic, strong) NSDictionary *dictParams;

/// 成功回调
@property (nonatomic, copy) MPHNetFinishedBlock blkSuccess;

/// 失败回调
@property (nonatomic, copy) MPHNetFinishedBlock blkFailed;

/// 缓存数据回调
@property (nonatomic, copy) MPHNetCatcheBlock blkCache;

/// 会话过期会回调此block
@property (nonatomic, copy) void (^sessionTimeoutBlock)(MPE_NetWorkSessionState state);

/// 无网络回调
@property (nonatomic, copy) BOOL (^noNetWorkShowBlock)(void);

/// 网络请求失败时是否需要弹框提示。YES（默认）有弹框提示；NO 无弹框提示
@property (nonatomic, assign) BOOL isShowToastView4NetWorkState;

/// 参数是否需要加密
@property (nonatomic, assign) BOOL isNeedEncrypt;

/// 依赖请求
@property (nonatomic, assign) MPMNetRequestModel *dependModel;

/// 依赖类型，默认 success
@property (nonatomic, assign) GMNetDependencyType optionDependType;

/// 依赖请求
@property (nonatomic, strong) NSMutableArray *maryDependencyRequest;

/// 网络请求对象
@property (nonatomic, strong) NSMutableArray *maryRequest;

/// 新旧api版本
@property (nonatomic, assign) BOOL isOldApi;
@property (nonatomic, assign) MPE_NetRespSecType enumResponseSecType;

@end


@implementation MPMNetRequestModel


+ (instancetype)defaultModel
{
    MPMNetRequestModel *defaultModel = [[MPMNetRequestModel alloc] init];
    
    return defaultModel;
}

+ (void)requset:(NSArray *)requests
{
    for (MPMNetRequestModel *modelR in requests)
    {
        if (modelR.dependModel)
        {
            [modelR.dependModel addDependencyRequest:modelR];
        }
        else
        {
            [modelR request];
        }
    }
}

- (void)addDependencyRequest:(MPMNetRequestModel *)model
{
    [_maryDependencyRequest addObject:model];
}

- (void)request
{
    __weak typeof(self) weakSelf = self;
    MPBNetWorking *netWorking;
    if (_classReq)
    {
        netWorking = [[_classReq alloc] init];
    }
    else
    {
        netWorking = [[MPBNetWorking alloc] init];
    }
    
    netWorking.oldApi = self.isOldApi;
    netWorking.responseSecType  = self.enumResponseSecType;
    [self.maryRequest addObject:netWorking];
    __weak typeof(MPBNetWorking *) weakNet = netWorking;

    netWorking.timeoutInterval = self.timeoutInterval;
    netWorking.sessionTimeoutBlock = self.sessionTimeoutBlock;
    netWorking.isShowToastView4NetWorkState = self.isShowToastView4NetWorkState;
    netWorking.priority = self.priorityTask;
    netWorking.noNetWorkBlock = ^BOOL
    {
        [weakSelf.maryRequest removeObject:weakNet];
        
        if (weakSelf.noNetWorkShowBlock)
        {
           return weakSelf.noNetWorkShowBlock();
        }

        return YES;
    };
    
    
    if (self.blkCache)
    {
        [netWorking netWorkWithMethod:_enumNetMethod
                                  URL:_strUrl
                               params:_dictParams
                     isShowNoNetAlert:_isShowNoNetAlert
                            isEncrypt:_isNeedEncrypt
                              success:^(MPBNetWorking *netWork, MPURLSessionTask *operation)
         {
             MPHNetFinishedBlock blkSuccessTemp = weakSelf.blkSuccess;
             if (blkSuccessTemp)
             {
                 blkSuccessTemp(netWork, operation);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencySuccess)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];
         }
                               failed:^(MPBNetWorking *netWork, MPURLSessionTask *operation)
         {
             MPHNetFinishedBlock blkFailedTemp = weakSelf.blkFailed;
             if (blkFailedTemp)
             {
                 blkFailedTemp(netWork, operation);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencyFailed)
                 {
                     [modelR request];
                 }
             }
            
             [weakSelf.maryRequest removeObject:netWork];
         }
                               cached:^(NSDictionary *cachedObject)
         {
             MPHNetCatcheBlock blkCacheTemp = weakSelf.blkCache;
             if (blkCacheTemp)
             {
                 blkCacheTemp(cachedObject);
             }
             
             [weakSelf.maryRequest removeObject:weakNet];
         }];
    }
    else
    {
        [netWorking netWorkWithMethod:_enumNetMethod
                                  URL:_strUrl
                               params:_dictParams
                     isShowNoNetAlert:_isShowNoNetAlert
                            isEncrypt:_isNeedEncrypt
                              success:^(MPBNetWorking *netWork, MPURLSessionTask *operation)
         {
             MPHNetFinishedBlock blkSuccessTemp = weakSelf.blkSuccess;
             if (blkSuccessTemp)
             {
                 blkSuccessTemp(netWork, operation);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencySuccess)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];
         }
                               failed:^(MPBNetWorking *netWork, MPURLSessionTask *operation)
         {
             MPHNetFinishedBlock blkFailedTemp = weakSelf.blkFailed;
             if (blkFailedTemp)
             {
                 blkFailedTemp(netWork, operation);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencyFailed)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];
         }
                               cached:^(NSDictionary *cachedObject)
        {
                                   
            [weakSelf.maryRequest removeObject:weakNet];
        }];
        
    }
}

- (void)syncRequest
{
    __weak typeof(self) weakSelf = self;
    MPBNetWorking *netWorking;
    if (_classReq)
    {
        netWorking = [[_classReq alloc] init];
    }
    else
    {
        netWorking = [[MPBNetWorking alloc] init];
    }
    
    netWorking.oldApi = self.isOldApi;
    netWorking.responseSecType = self.enumResponseSecType;
    
    [self.maryRequest addObject:netWorking];
    
    __weak typeof(MPBNetWorking *) weakNet = netWorking;

    netWorking.timeoutInterval = self.timeoutInterval;
    netWorking.priority = self.priorityTask;
    netWorking.noNetWorkBlock = ^BOOL
    {
        [weakSelf.maryRequest removeObject:weakNet];
        
        return YES;
    };
    
    if (self.blkCache)
    {
        [netWorking netWorkSyncWithMethod:_enumNetMethod
                                      URL:_strUrl
                                   params:_dictParams
                         isShowNoNetAlert:_isShowNoNetAlert
                                isEncrypt:_isNeedEncrypt
                                  success:^(MPBNetWorking *netWork, id responseObject)
         {
             MPHNetFinishedBlock blkSuccessTemp = weakSelf.blkSuccess;
             if (blkSuccessTemp)
             {
                 blkSuccessTemp(netWork, nil);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencySuccess)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];

         }
                                   failed:^(MPBNetWorking *netWork, id responseObject)
         {
             MPHNetFinishedBlock blkFailedTemp = weakSelf.blkFailed;
             if (blkFailedTemp)
             {
                 blkFailedTemp(netWork, nil);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencyFailed)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];
         }
                                   cached:^(NSDictionary *cachedObject)
         {
             MPHNetCatcheBlock blkCacheTemp = weakSelf.blkCache;
             if (blkCacheTemp)
             {
                 blkCacheTemp(cachedObject);
             }
             
             [weakSelf.maryRequest removeObject:netWorking];
         }];
    }
    else
    {
        [netWorking netWorkSyncWithMethod:_enumNetMethod
                                      URL:_strUrl
                                   params:_dictParams
                         isShowNoNetAlert:_isShowNoNetAlert
                                isEncrypt:_isNeedEncrypt
                                  success:^(MPBNetWorking *netWork, id responseObject)
         {
             MPHNetFinishedBlock blkSuccessTemp = weakSelf.blkSuccess;
             if (blkSuccessTemp)
             {
                 blkSuccessTemp(netWork, nil);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencySuccess)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];
         }
                                   failed:^(MPBNetWorking *netWork, id responseObject)
         {
             MPHNetFinishedBlock blkFailedTemp = weakSelf.blkFailed;
             if (blkFailedTemp)
             {
                 blkFailedTemp(netWork, nil);
             }
             
             for (MPMNetRequestModel *modelR in weakSelf.maryDependencyRequest)
             {
                 if (modelR.optionDependType & GMNetDependencyFailed)
                 {
                     [modelR request];
                 }
             }
             
             [weakSelf.maryRequest removeObject:netWork];
         }
                                   cached:^(NSDictionary *cachedObject)
         {
             
             [weakSelf.maryRequest removeObject:weakNet];
         }];
        
    }
}

- (instancetype)init
{
    if (self = [super init])
    {
        _enumNetMethod = MPE_POST;
        _optionDependType = GMNetDependencySuccess;
        _timeoutInterval = MPDefaultRequestTimeoutInterval;
        _isShowNoNetAlert = MPDefautShowNoNetViewState;
        _isShowToastView4NetWorkState = MPDefautShowToastState;
        _isNeedEncrypt = MPDefautIsEncrypt;
        _maryDependencyRequest = [NSMutableArray array];
        _maryRequest = [NSMutableArray array];
    }
    
    return self;
}

- (void)dealloc
{
    NSLog(@"============> %s", __func__);
    
    [self.maryRequest removeAllObjects];
}

- (MPMNetRequestModel * (^)(MPE_NetMethod))method
{
    return ^MPMNetRequestModel *(MPE_NetMethod method)
    {
        self.enumNetMethod = method;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(NSString *))url
{
    return ^MPMNetRequestModel *(NSString *url)
    {
        self.strUrl = url;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(NSDictionary *))params
{
    return ^MPMNetRequestModel *(NSDictionary *params)
    {
        self.dictParams = params;
        
        return self;
    };
}

/**
 是否显示无网提示
 */
- (MPMNetRequestModel * (^)(BOOL))showNoNetAlert
{
    return ^MPMNetRequestModel *(BOOL isShow)
    {
        self.isShowNoNetAlert = isShow;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(MPHNetFinishedBlock))success
{
    return ^MPMNetRequestModel *(MPHNetFinishedBlock success)
    {
        self.blkSuccess = success;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(MPHNetFinishedBlock))failed
{
    return ^MPMNetRequestModel *(MPHNetFinishedBlock failed)
    {
        self.blkFailed = failed;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(MPHNetCatcheBlock))cache
{
    return ^MPMNetRequestModel *(MPHNetCatcheBlock cache)
    {
        self.blkCache = cache;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(void (^)(MPE_NetWorkSessionState state)))sessionTimeout
{
    return ^MPMNetRequestModel *(void (^sessionTimeout)(MPE_NetWorkSessionState state))
    {
        self.sessionTimeoutBlock = sessionTimeout;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(MPHNoNetWorkBlock))noNetWorkBlock
{
    return ^MPMNetRequestModel *(BOOL (^noNetWorkBlock)(void))
    {
        self.noNetWorkShowBlock = noNetWorkBlock;
        
        return self;
    };
}


- (MPMNetRequestModel * (^)(BOOL))showToast
{
    return ^MPMNetRequestModel *(BOOL showToast)
    {
        self.isShowToastView4NetWorkState = showToast;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(BOOL))isEncrypt
{
    return ^MPMNetRequestModel *(BOOL isEncrypt)
    {
        self.isNeedEncrypt = isEncrypt;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(CGFloat))timeout
{
    return ^MPMNetRequestModel *(CGFloat timeout)
    {
        self.timeoutInterval = timeout;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(CGFloat))priority
{
    return ^MPMNetRequestModel *(CGFloat priority)
    {
        self.priorityTask = priority;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(Class))requestTypeClass
{
    return ^MPMNetRequestModel *(Class requestTypeClass)
    {
        self.classReq = requestTypeClass;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(MPMNetRequestModel *))depend
{
    return ^MPMNetRequestModel *(MPMNetRequestModel *depend)
    {
        self.dependModel = depend;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(GMNetDependencyType))optionDepend
{
    return ^MPMNetRequestModel *(GMNetDependencyType optionDepend)
    {
        self.optionDependType = optionDepend;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(BOOL))oldApi
{
    return ^MPMNetRequestModel *(BOOL oldApi)
    {
        self.isOldApi = oldApi;
        
        return self;
    };
}

- (MPMNetRequestModel * (^)(MPE_NetRespSecType))responseSecType
{
    return ^MPMNetRequestModel *(MPE_NetRespSecType responseSecType)
    {
        self.enumResponseSecType = responseSecType;
        
        return self;
    };
}



@end
